/************************************************************************/
/*    Author: Scott Bevin                                               */
/************************************************************************/

#pragma once

#include <stack>
#include <list>
#include <vector>
#include <algorithm>

#include "OctTreeNode.h"

namespace XF
{
	class OctTreeIterator
	{
	private:
		std::stack<OctTreeNode*> mCurrentNodes;
		std::list<OctTreeNode*> mVisitedNodes;

	public:
		OctTreeIterator(OctTreeNode *startNode)
		{
			mCurrentNodes.push(startNode);
		}
		~OctTreeIterator(){}

		bool End(){return (mCurrentNodes.size() <= 0);}
		OctTreeNode* CurrentNode(){return mCurrentNodes.top();}

		void Increment()
		{
			if(CurrentNode()->HasChildNodes() 
				&& std::find(mVisitedNodes.begin(), mVisitedNodes.end(), CurrentNode()) == mVisitedNodes.end())
			{
				std::vector<OctTreeNode*> children = CurrentNode()->GetChildNodes();

				for(int i = 0; i < 8; ++i)
				{
					mCurrentNodes.push(children[i]);
				}
			}
			else
			{
				mVisitedNodes.push_back(CurrentNode());
				mCurrentNodes.pop();
			}
		}
	};
}